home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Environments / Small Eiffel 0.4.8 / lib_std / linked_collection.e < prev    next >
Encoding:
Text File  |  1997-04-13  |  5.8 KB  |  320 lines  |  [TEXT/ttxt]

  1. -- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C) 
  2. -- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
  3. --
  4. deferred class LINKED_COLLECTION[E]
  5.    -- 
  6.    -- Common root for LINK_LIST[E] and LINK2_LIST[E].
  7.    --
  8.  
  9. inherit COLLECTION[E] redefine first, last end;
  10.  
  11. feature
  12.  
  13.    lower: INTEGER is 1;
  14.      -- Lower index bound is frozen.
  15.    
  16. feature {LINKED_COLLECTION}
  17.    
  18.    first_link: LINK[E];
  19.      -- Void when empty or gives access to the first element.
  20.  
  21.    last_link: like first_link; 
  22.      -- Void when empty or gives access to the last element.
  23.  
  24.    mem_idx: INTEGER; mem_lnk: like first_link; 
  25.      -- To speed up accessing, `mem_idx' and `mem_lnk' is the 
  26.      -- memory of the last access done. For example, after 
  27.      -- item(1), `mem_idx' is 1 and `mem_lnk' is `first_link'.
  28.      -- When list is empty, `first_link' is Void as well as 
  29.      -- `mem_lnk' and `mem_idx' is 0;
  30.      -- 
  31. feature
  32.    
  33.    upper: INTEGER;
  34.      -- Memorized upper index bound.
  35.  
  36. feature -- Creation and Modification :
  37.  
  38.    make is
  39.       -- Make an empty list;
  40.       deferred
  41.       end;
  42.  
  43. feature
  44.    
  45.    first: like item is
  46.       do
  47.      Result := first_link.item;
  48.       end;
  49.    
  50.    last: like item is
  51.       do
  52.      Result := last_link.item;
  53.       end;
  54.  
  55. feature -- Implementation of deferred :
  56.  
  57.    item, infix "@" (index: INTEGER): E is
  58.       do
  59.      if index /= mem_idx then
  60.         go_item(index);
  61.      end;
  62.      Result := mem_lnk.item;
  63.       end;
  64.    
  65.    put(element: like item; index: INTEGER) is
  66.       do
  67.      if index /= mem_idx then
  68.         go_item(index);
  69.      end;
  70.      mem_lnk.set_item(element);
  71.       end;
  72.  
  73.    count: INTEGER is
  74.       do
  75.      Result := upper;
  76.       end;
  77.  
  78.    set_all_with(v: like item) is
  79.       do
  80.      if first_link /= Void then
  81.         first_link.set_all_with(v);
  82.      end;
  83.       end;
  84.  
  85.    copy(other: like Current) is
  86.       do
  87.      from_collection(other);
  88.       end;
  89.  
  90.    is_equal(other: like Current): BOOLEAN is
  91.       local
  92.      lnk1, lnk2: like first_link;
  93.       do
  94.      if Current = other then
  95.         Result := true;
  96.      elseif upper = other.upper then
  97.         from
  98.            Result := true;
  99.            lnk1 := first_link;
  100.            lnk2 := other.first_link;
  101.         until
  102.            lnk1 = Void or not Result
  103.         loop
  104.            Result := equal_like(lnk1.item,lnk2.item);
  105.            lnk1 := lnk1.next;
  106.            lnk2 := lnk2.next;
  107.         end;        
  108.      end;
  109.       end;
  110.  
  111.    index_of(x: like item): INTEGER is
  112.       do
  113.      from  
  114.         Result := lower;
  115.      until
  116.         (Result > upper) or else equal_like(x,item(Result))
  117.      loop
  118.         Result := Result + 1;
  119.      end;
  120.       end;
  121.    
  122.    fast_index_of(x: like item): INTEGER is
  123.       local
  124.      u: like upper;
  125.       do
  126.      from
  127.         Result := lower;
  128.         u := upper;
  129.      until
  130.         (Result > u) or else x = item(Result)
  131.      loop
  132.         Result := Result + 1;
  133.      end;
  134.       end;
  135.    
  136.    clear is
  137.       do
  138.      if first_link /= Void then
  139.         first_link.free;
  140.         first_link := Void;
  141.         mem_idx := 0;
  142.         mem_lnk := Void;
  143.         upper := 0;
  144.         last_link := Void;
  145.      end;
  146.       ensure then
  147.      upper = 0
  148.       end;
  149.  
  150.    from_collection(model: COLLECTION[like item]) is
  151.       local
  152.      i, up: INTEGER;
  153.      lnk: like first_link;
  154.       do
  155.      if first_link = Void then
  156.         from
  157.            i := model.lower;
  158.            up := model.upper;
  159.         until
  160.            i > up
  161.         loop
  162.            add_last(model.item(i));
  163.            i := i + 1;
  164.         end;
  165.      else
  166.         from
  167.            lnk := first_link;
  168.            i := model.lower;
  169.            up := model.upper;
  170.         until
  171.            i > up
  172.         loop
  173.            if lnk = Void then
  174.           add_last(model.item(i));
  175.            else
  176.           lnk.set_item(model.item(i));
  177.           lnk := lnk.next;
  178.            end;
  179.            i := i + 1;
  180.         end;
  181.         if lnk = first_link then
  182.            check
  183.           model.count = 0
  184.            end;
  185.            clear;
  186.         elseif lnk /= Void then
  187.            i := model.count;
  188.            if mem_idx /= i then
  189.           go_item(i);
  190.            end;
  191.            check
  192.           lnk = mem_lnk.next
  193.            end;
  194.            mem_lnk.set_next(Void);
  195.            upper := i;
  196.            last_link := mem_lnk;
  197.            lnk.free;
  198.         end;
  199.      end;
  200.       end;
  201.  
  202.    slice(low, up: INTEGER): like Current is
  203.       local
  204.      lnk: like first_link;
  205.      i: INTEGER;
  206.       do
  207.      from
  208.         !!Result.make;
  209.         if mem_idx /= low then
  210.            go_item(low);
  211.         end;
  212.         lnk := mem_lnk;
  213.         i := up - low + 1;
  214.      until
  215.         i = 0
  216.      loop
  217.         Result.add_last(lnk.item);
  218.         lnk := lnk.next;
  219.         i := i - 1;
  220.      end;
  221.       end;
  222.  
  223.    nb_occurrences(element: like item): INTEGER is
  224.       local
  225.      lnk: like first_link;
  226.       do
  227.      from
  228.         lnk := first_link;
  229.      until
  230.         lnk = Void
  231.      loop
  232.         if equal_like(element,lnk.item) then
  233.            Result := Result + 1;
  234.         end;
  235.         lnk := lnk.next;
  236.      end;
  237.       end;
  238.  
  239.    free is 
  240.       local
  241.      mem: MEMORY;
  242.       do
  243.      clear;
  244.      mem.free(Current.to_pointer);
  245.       end;
  246.  
  247.    force(element: E; index: INTEGER) is
  248.       local
  249.      v: like element;
  250.       do
  251.      from
  252.      until
  253.         index <= upper
  254.      loop
  255.         add_last(v);
  256.      end;
  257.      put(element,index);
  258.       end;
  259.  
  260.    all_cleared: BOOLEAN is
  261.       local
  262.      l: like first_link;
  263.      d: like item;
  264.       do
  265.      from
  266.         Result := true;
  267.         l := first_link;
  268.      until
  269.         not Result or else l = Void
  270.      loop
  271.         Result := d = l.item;
  272.         l := l.next;
  273.      end;
  274.       end;
  275.  
  276.    remove_last is
  277.       local
  278.      mem: MEMORY;
  279.       do
  280.      if upper = 1 then
  281.         make;
  282.      else
  283.         if upper - 1 /= mem_idx then
  284.            go_item(upper - 1);
  285.         end;
  286.         upper := upper - 1;
  287.         mem.free(last_link.to_pointer);
  288.         last_link := mem_lnk;
  289.         last_link.set_next(Void);
  290.      end;
  291.       end;
  292.  
  293. feature {NONE}
  294.  
  295.    go_item(index: INTEGER) is
  296.       require
  297.      valid_index(index);
  298.      mem_idx /= index;
  299.            mem_idx > 0;
  300.      mem_lnk /= Void
  301.       deferred
  302.       ensure
  303.      mem_idx = index;
  304.      mem_lnk /= Void
  305.       end;
  306.  
  307. invariant
  308.  
  309.    empty_status:
  310.       first_link = Void implies 
  311.          (last_link = Void and upper = 0 and mem_idx = 0 
  312.       and mem_lnk = Void);
  313.  
  314.    not_empty_status:
  315.       first_link /= Void implies 
  316.          (last_link /= Void and upper > 0 and mem_idx > 0 
  317.       and mem_lnk /= Void);
  318.    
  319. end -- LINKED_COLLECTION[E]
  320.